/*
 * ThreadTrap.java
 * - compute execution time
 * - create threads to do the computation.
 * - sum the integral from threads.
 */
import java.util.*;
import java.text.*;
public class Trap extends Thread {
	
	private int numThread;
	private int numIntegral;    /* local Integral */
	private double left, right, base;
	private double intergral; /* store final value */
	private Vector<ThreadTrap> worker;
	private TimeStamp ts;
	private boolean debug;
	private Thread t;
	
	public Trap() {
		
	}// end default constructor
	
	public Trap(int numThread, int numIntegral, double left, double right, boolean debug, boolean thread) {
	
		this.debug = debug;
		this.numThread = numThread;
		this.numIntegral = numIntegral;		
		this.left = left;
		this.right = right;
		intergral = 0.0;
		base = (right - left) / numThread;
		worker = new Vector<ThreadTrap>();
		ts = new TimeStamp();
		
		if(thread) {
			this.numThread = 1;
			t = new Thread(this);
			t.start();
		}
		else {
			trapazoid();
		}
	}// // end overload constructor
	
	
	public void run() {
		trapazoid();
	}// end method run
	
	public void trapazoid() {
		ts.start();
		if(numThread == 1) {
			worker.add(new ThreadTrap(numIntegral, left, right));
			ts.stop();
		}
		else {
			for(int tid = 0; tid < numThread; tid++) {
				left = base * (tid);
				right = base * (tid+1);
				if(debug) System.out.println("Child Thread " + tid + " has interval from " + left + " to " + right);
				worker.add(new ThreadTrap(numIntegral, left, right));
			}
			
			// wait for all the threads finish their work
			try {
				for(int i = 0; i < numThread; i++) {
					worker.elementAt(i).getThread().join();
				}
				
			}
			catch(InterruptedException e) {	
				System.out.println("Main thread Interrupted");
				e.printStackTrace();
			}
			
			for(int i = 0; i < numThread; i++) {
				if(debug) System.out.println("Intregral form Child thread " + i + " is " + worker.elementAt(i).getIntegral());
				intergral += worker.elementAt(i).getIntegral();
			}
			
			ts.stop();
		}
		if(debug) {
			System.out.println("Done computing trapaziod.");
			printResult();
		}
	}// end method trapazoid
	
	private void printResult() {
		System.out.println(this.getName());
		System.out.println("execution time for trapezoid workload is: "
				+ ts.elapsedTime() + " nanoseconds.");
		System.out.println();
	}// end method printResult
	
	
	public double getExecutionTime() {
		return this.ts.elapsedTime();
	}// end method getExecutionTime
}// end class Trap
